﻿using nRoute.Components;
using nRoute.Navigation.Mapping;
using nRoute.Samples.Netflix.Data.Catalog;
using nRoute.Samples.Netflix.Views;
using nRoute.ViewModels;

namespace nRoute.Samples.Netflix.ViewModels
{
    [DefineNavigationContent("Content/Netflix/Person/", typeof(PersonView))]
    [MapViewModel(typeof(PersonView))]
    public class PersonViewModel
        : NavigationViewModelBase
    {
        private const string PERSON_KEY = "Person";
        private const string TITLE_FORMAT = "Person: {0}";

        private int _loadingToken = 0;

#region Properties

        public Person Person { get; private set; }

        public bool IsLoading { get; private set; }

#endregion

#region Overrides

        protected override void OnIntialize(ParametersCollection state)
        {
            // if no data is passed in on initialization, it means it will be restored from state
            if (!state.ContainsKey(PERSON_KEY)) return;
            SetupPerson((Person)state[PERSON_KEY]);
        }

        protected override void OnRestoreState(ParametersCollection state)
        {
            // if person is already loaded we don't load again
            if (Person != null) return;

            if (state.ContainsKey(PERSON_KEY))
            {
                SetupPerson((Person)state[PERSON_KEY]);
            }
            else
            {
                // inform no loaded data
            }
        }

        protected override ParametersCollection OnSaveState()
        {
            if (Person != null)
            {
                return new ParametersCollection() 
                { 
                    new Parameter(PERSON_KEY, Person)
                };
            }
            else
            {
                return null;
            }
        }

#endregion

#region Helpers

        private void SetupPerson(Person person)
        {
            base.Title = string.Format(TITLE_FORMAT, person.Name);
            this.Person = person;

            if (person.TitlesActedIn.Count == 0)
            {
                _loadingToken += 1;
                person.TitlesActedIn.LoadAsync();
                person.TitlesActedIn.LoadCompleted += TitlesActedIn_LoadCompleted;
            }
            if (person.TitlesDirected.Count == 0)
            {
                _loadingToken += 1;
                person.TitlesDirected.LoadAsync();
                person.TitlesDirected.LoadCompleted += TitlesDirected_LoadCompleted;
            }

            if (_loadingToken > 0 && Person.TitlesActedIn.Count == 0 && person.TitlesDirected.Count == 0)
            {
                IsLoading = true;
                NotifyPropertyChanged(() => IsLoading);
            }
            NotifyPropertyChanged(() => Person);
        }

        private void TitlesActedIn_LoadCompleted(object sender, System.Data.Services.Client.LoadCompletedEventArgs e)
        {
            _loadingToken -= 1;
            if (_loadingToken == 0)
            {
                IsLoading = false;
                NotifyPropertyChanged(() => IsLoading);
                NotifyPropertyChanged(() => Person);
            }
        }

        private void TitlesDirected_LoadCompleted(object sender, System.Data.Services.Client.LoadCompletedEventArgs e)
        {
            _loadingToken -= 1;
            if (_loadingToken == 0)
            {
                IsLoading = false;
                NotifyPropertyChanged(() => IsLoading);
                NotifyPropertyChanged(() => Person);
            }            
        }

#endregion

    }
}